<template>
  <div>
    <div class="target" :style="circleStyle">
      <div>x= {{ circleConfig.x }}</div>
      <div>y= {{ circleConfig.y }}</div>
    </div>
    <div class="circle" :style="circleStyle"></div>
    <div class="pointers" v-for="(item, key) in 360" :key="key" :style="pointerStyle(key)"></div>
    <div
      class="pointer"
      :style="{
        left: `${pointer.x}px`,
        top: `${pointer.y}px`,
        rotate: `${circleConfig.rotate}deg`,
        width: `${pointer.w}px`,
        height: `${pointer.h}px`,
      }"
    >
      <div>x= {{ pointer.x }}</div>
      <div>y= {{ pointer.y }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, type CSSProperties } from 'vue'

/* 根据宽高，获取对应圆的半径 */
const getCircleRadius = (w: number, h: number) => Math.sqrt(w ** 2 + h ** 2)

const pointer = ref({
  x: 0,
  y: 0,
  w: 100,
  h: 100,
})
/* 弧度转角度 */
const r2d = (r: number) => {
  return (r * Math.PI) / 180
}

/** 根据半径，和旋转角度，获取圆上的点
 * @param {number} r 圆的半径
 * @param {number} deg 角度
 */
const getPointByDeg = (r: number, deg: number) => {
  const x = r * Math.cos(r2d(deg))
  const y = r * Math.sin(r2d(deg))

  return { x, y }
}

/**
 * 根据坐标计算角度
 * @param {number} x
 * @param {number} y
 */
const calculateAngle = (x: number, y: number, w: number, h: number): number => {
  return (Math.atan2(y - h, x - w) * 180) / Math.PI
}

const circleConfig = ref({
  r: getCircleRadius(50, 50),
  x: 200,
  y: 200,
  w: 200,
  h: 200,
  rotate: 45,
})

const circleStyle = computed((): CSSProperties => {
  return {
    left: `${circleConfig.value.x}px`,
    top: `${circleConfig.value.y}px`,
    rotate: `${circleConfig.value.rotate}deg`,
    width: `${circleConfig.value.w}px`,
    height: `${circleConfig.value.h}px`,
  }
})

const startDeg = calculateAngle(
  pointer.value.x,
  pointer.value.y,
  circleConfig.value.w,
  circleConfig.value.h,
)

setInterval(() => {
  const p = getPointByDeg(circleConfig.value.r, circleConfig.value.rotate++ + startDeg)

  pointer.value.x = circleConfig.value.x + circleConfig.value.w / 2 + p.x
  pointer.value.y = circleConfig.value.y + circleConfig.value.h / 2 + p.y
}, 0)

const pointerStyle = (i: number): CSSProperties => {
  const { x, y } = getPointByDeg(circleConfig.value.r, i)

  return {
    left: `${circleConfig.value.x + circleConfig.value.w / 2 + x}px`,
    top: `${circleConfig.value.y + circleConfig.value.h / 2 + y}px`,
    opacity: i % 12 === 0 ? 1 : 0,
  }
}
</script>

<style lang="scss" scoped>
.circle,
.target {
  width: 100px;
  height: 100px;
  position: absolute;
  border: 1px solid #000;
  z-index: 10;
}
.target {
  outline: 2px solid #f01daa;
  z-index: 100;
}
.pointers {
  width: 10px;
  height: 10px;
  border: 1px solid blue;
  position: absolute;
}
.pointer {
  position: absolute;
  border: 1px solid #000;
  transform-origin: 0% 0%;
}
</style>
